use crate::wcferry::wcf::{
    AttachMsg, AudioMsg, DbNames, DbQuery, DbTables, DecPath, ForwardMsg, MemberMgmt, MsgTypes,
    PatMsg, PathMsg, RichText, RpcContacts, TextMsg, Transfer, Verification,
};
use crate::wcferry::{self, RoomMember, SelfInfo};
use crate::WCFERRY;
use anyhow::anyhow;
use log::debug;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use utoipa::ToSchema;

#[derive(Debug, Serialize, Deserialize)]
pub struct Image {
    /// 消息里的 id
    id: u64,
    /// 消息里的 extra
    extra: String,
    /// 存放目录，不存在则失败；没权限，亦失败
    dir: String,
    /// 超时时间，单位秒
    timeout: u8,
}

#[derive(Serialize, Deserialize, Debug, Clone, ToSchema)]
#[serde(untagged)]
pub enum FieldContent {
    Int(i64),
    Float(f64),
    Utf8String(String),
    Base64String(String),
    None,
}

pub struct WcferryUtil {
    wcferry_client: wcferry::WeChat,
}

impl WcferryUtil {
    pub fn new() -> anyhow::Result<Self> {
        let wcferry_client = WCFERRY.get().ok_or(anyhow!("wechat error"))?;
        Ok(Self {wcferry_client: wcferry_client.clone()})
    }

    /// 查询登录状态
    pub fn is_login(&self) -> anyhow::Result<bool> {
        self.wcferry_client.is_login()
    }

    /// 查询登录 wxid
    pub fn get_self_wxid(&self) -> anyhow::Result<String> {
        
        self.wcferry_client.get_self_wxid()
    }

    /// 获取登录账号信息
    pub fn get_user_info(&self) -> anyhow::Result<SelfInfo> {
        
        self.wcferry_client.get_user_info()
    }

    /// 获取所有联系人
    pub fn get_contacts(&self) -> anyhow::Result<RpcContacts> {
        
        self.wcferry_client.get_contacts()
    }

    /// 获取所有可查询数据库
    pub fn get_dbs(&self) -> anyhow::Result<DbNames> {
        
        self.wcferry_client.get_dbs()
    }

    /// 查询数据库下的表信息
    pub fn get_tables(&self,db: String) -> anyhow::Result<DbTables> {
        
        self.wcferry_client.get_tables(db)
    }

    ///获取消息类型
    pub fn get_msg_types(&self) -> anyhow::Result<MsgTypes> {
        
        self.wcferry_client.get_msg_types()
    }

    ///发送文本消息
    pub fn send_text(&self,text_msg: TextMsg) -> anyhow::Result<bool> {
        
        self.wcferry_client.send_text(text_msg)
    }

    /// 发送图片
    pub fn send_image(&self,path_msg: PathMsg) -> anyhow::Result<bool> {
        
        self.wcferry_client.send_image(path_msg)
    }

    ///发送文件
    pub fn send_file(&self,path_msg: PathMsg) -> anyhow::Result<bool> {
        
        self.wcferry_client.send_file(path_msg)
    }

    ///发送卡片消息
    pub fn send_rich_text(&self,msg: RichText) -> anyhow::Result<bool> {
        
        self.wcferry_client.send_rich_text(msg)
    }

    /// 发送拍一拍消息
    pub fn send_pat_msg(&self,msg: PatMsg) -> anyhow::Result<bool> {
        
        self.wcferry_client.send_pat_msg(msg)
    }

    ///转发消息
    pub fn forward_msg(&self,msg: ForwardMsg) -> anyhow::Result<bool> {
        
        self.wcferry_client.forward_msg(msg)
    }

    /// 保存语音消息
    pub fn save_audio(&self,msg: AudioMsg) -> anyhow::Result<String> {
        
        self.wcferry_client.save_audio(msg)
    }

    /// 保存图片
    pub fn save_image(&self,msg: Image) -> anyhow::Result<bool> {
        

        let attach_msg = AttachMsg {
            id: msg.id,
            thumb: "".to_string(),
            extra: msg.extra.clone(),
        };

        let result = self.wcferry_client.download_attach(attach_msg)?;
        if result {
            let t = self.wcferry_client.decrypt_image(DecPath {
                src: msg.extra.clone(),
                dst: msg.dir.clone(),
            })?;
            debug!("解码的图片 = {:?}", t);
            Ok(true)
        } else {
            Ok(false)
        }
    }

    /// 接收转账
    pub fn recv_transfer(&self,msg: Transfer) -> anyhow::Result<bool> {
        
        self.wcferry_client.recv_transfer(msg)
    }

    /// 执行 SQL 查询数据库
    pub fn query_sql(&self,msg: DbQuery) -> anyhow::Result<Vec<HashMap<String, FieldContent>>> {
        
        match self.wcferry_client.query_sql(msg) {
            Ok(origin) => {
                let rows = origin
                    .rows
                    .into_iter()
                    .map(|r| {
                        let mut row_map = HashMap::new();
                        for f in r.fields {
                            let utf8 = String::from_utf8(f.content.clone()).unwrap_or_default();
                            let content: FieldContent = match f.r#type {
                                1 => utf8
                                    .parse::<i64>()
                                    .map_or(FieldContent::None, FieldContent::Int),
                                2 => utf8
                                    .parse::<f64>()
                                    .map_or(FieldContent::None, FieldContent::Float),
                                3 => FieldContent::Utf8String(utf8),
                                4 => FieldContent::Base64String(base64::encode(f.content)),
                                _ => FieldContent::None,
                            };
                            row_map.insert(f.column, content);
                        }
                        row_map
                    })
                    .collect::<Vec<_>>();
                Ok(rows)
            }
            Err(error) => Err(anyhow!(error)),
        }
    }

    /// 通过好友申请
    pub fn accept_new_friend(&self,msg: Verification) -> anyhow::Result<bool> {
        
        self.wcferry_client.accept_new_friend(msg)
    }

    ///添加群成员
    pub fn add_chatroom_member(&self,msg: MemberMgmt) -> anyhow::Result<bool> {
        
        self.wcferry_client.add_chatroom_member(msg)
    }

    /// 邀请群成员
    pub fn invite_chatroom_member(&self,msg: MemberMgmt) -> anyhow::Result<bool> {
        
        self.wcferry_client.invite_chatroom_member(msg)
    }

    ///删除群成员（踢人）
    pub fn delete_chatroom_member(&self,msg: MemberMgmt) -> anyhow::Result<bool> {
        
        self.wcferry_client.delete_chatroom_member(msg)
    }

    ///  撤回消息
    pub fn revoke_msg(&self,id: u64) -> anyhow::Result<bool> {
        
        self.wcferry_client.revoke_msg(id)
    }

    /// 查询群成员
    pub fn query_room_member(&self,room_id: String) -> anyhow::Result<Option<Vec<RoomMember>>> {
        
        self.wcferry_client.query_room_member(room_id)
    }

    ///刷新朋友圈
    pub fn refresh_pyq(&self,id: u64) -> anyhow::Result<bool> {
        
        self.wcferry_client.refresh_pyq(id)
    }
}
